package org.elfen.common.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.elfen.common.json.JsonUtil;
import org.elfen.common.result.Result;
import org.elfen.common.util.DataUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TokenFilter implements Filter {
	private static final Logger logger = LoggerFactory.getLogger(TokenFilter.class);
	private String tokenWhiteUrls;
	// 白名单
	private List<String> whiteUrls;
	private int _size = 0;
	private BaseTokenFilterOption tokenFilterOption;
	
	public TokenFilter(String tokenWhiteUrls,BaseTokenFilterOption tokenFilterOption) {
		super();
		this.tokenWhiteUrls = tokenWhiteUrls;
		this.tokenFilterOption = tokenFilterOption;
	}

	public void init(FilterConfig config) throws ServletException {
		whiteUrls = new ArrayList<String>();
		
		if(DataUtil.isNotEmpty(tokenWhiteUrls)){
			String[] urls = tokenWhiteUrls.split(";");
			for(String str: urls){
				if(DataUtil.isNotEmpty(str)){
					whiteUrls.add(str);
				}
			}
		}
		_size = null == whiteUrls ? 0 : whiteUrls.size();
		
	}

	public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		if (isWhiteReq(request.getRequestURI()) || "/".equals(request.getRequestURI())) {
			logger.info("无需token验证，直接访问！！！URI={}",request.getRequestURI());
			chain.doFilter(request, response);
		} else {
			logger.info("进行token验证,URI={}",request.getRequestURI());
			String tokenKey = request.getHeader("authorization");
			if (StringUtils.isNotBlank(tokenKey)) {
				try {
					tokenFilterOption.validateTokenInfo(tokenKey,request);
					chain.doFilter(request, response);
					return ;
					
				} catch (Exception e) {
					logger.error("进行Token认证,出现异常:", e);
				}
				
				logger.error("进行Token认证：身份认证失败！");
				doResponse(response,"401","身份认证失败！");
				return ;
			}else{
				logger.info("进行token验证,请求消息头中的authorization为空！authorization={}",tokenKey);
				doResponse(response,"400","请将身份认证信息放在请求Header中！");
				return ;
			}
		}
	}

	private void doResponse(ServletResponse response,String code,String msg) throws IOException {
		response.setContentType("text/html; charset=UTF-8");
		Result result = new Result();
		result.setMsg(msg);
		result.setSuccess(false);
		result.setObj(System.currentTimeMillis());
		PrintWriter out = response.getWriter();
		out.println(JsonUtil.toJson(result));
		out.flush();
		out.close();
	}

	public void destroy() {
	}

	/*
	 * 判断是否是白名单
	 */
	private boolean isWhiteReq(String requestUrl) {
		if (_size == 0) {
			return false;
		} else {
			for (String urlTemp : whiteUrls) {
				if (requestUrl.indexOf(urlTemp) > -1) {
					return true;
				}
			}
		}

		return false;
	}
}
